#include "usw/include/drv_common.h"
#include "usw/include/drv_io.h"
#include "drv_api.h"
#include "ctc_cli.h"
#include "ctc_dkit.h"
#include "usw/include/drv_ftm.h"
#include "usw/include/drv_enum.h"
#include "ctc_usw_dkit.h"
#include "ctc_usw_dkit_drv.h"
#include "ctc_usw_dkit_discard.h"
#include "ctc_usw_dkit_discard_type.h"
#include "ctc_usw_dkit_path.h"
#include "ctc_usw_dkit_captured_info.h"
#include "ctc_usw_dkit_tcam.h"
#include "ctc_usw_dkit_dump_tbl.h"


#define DRV_LPM_TCAM_KEY0_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY1_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY2_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY3_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY4_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY5_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY6_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY7_MAX_ENTRY_NUM                256*4
#define DRV_LPM_TCAM_KEY8_MAX_ENTRY_NUM                512*4
#define DRV_LPM_TCAM_KEY9_MAX_ENTRY_NUM                512*4
#define DRV_LPM_TCAM_KEY10_MAX_ENTRY_NUM               512*4
#define DRV_LPM_TCAM_KEY11_MAX_ENTRY_NUM               512*4

#define DS_QUEUE_MAP_TCAM_KEY_BYTES                    (DRV_IS_DUET2(lchip) ? 8 : sizeof(DsQueueMapTcamKey_m))


#define CTC_DKITS_INVALID_INDEX             0xFFFFFFFF
#define CTC_DKITS_INVALID_TBLID             0xFFFFFFFF
#define CTC_DKITS_FLOW_TCAM_BLK_NUM         17
#define CTC_DKITS_LPM_TCAM_BLK_NUM          12
#define CTC_DKITS_OCTO_BITS                  8

#define DKITS_TCAM_FLOW_TCAM_BLK_BITS            5
#define DKITS_TCAM_IP_TCAM_BLK_BITS              2
#define DKITS_TCAM_NAT_TCAM_BLK_BITS             2

#define DKITS_TCAM_FLOW_DETECT_MEM_NUM           1
#define DKITS_TCAM_DETECT_MEM_NUM                1
#define DKITS_TCAM_BLOCK_INVALID_TYPE            0xFF
#define DRV_TIME_OUT                             1000    /* Time out setting */
#define CTC_DKITS_TCAM_TYPE_FLAG_NUM             7
#define CTC_DKITS_TCAM_DETECT_MAX_REQ            8

#define CTC_DKITS_TCAM_FLOW_TCAM_DETECT_BIST_DELAY       2
#define CTC_DKITS_TCAM_FLOW_TCAM_DETECT_CAPTURE_DELAY    1

#define CTC_DKITS_TCAM_LPM_TCAM_DETECT_BIST_DELAY        4
#define CTC_DKITS_TCAM_LPM_TCAM_DETECT_CAPTURE_DELAY     4

#define CTC_DKITS_TCAM_CID_TCAM_DETECT_BIST_DELAY        1
#define CTC_DKITS_TCAM_CID_TCAM_DETECT_CAPTURE_DELAY     2

#define CTC_DKITS_TCAM_QUE_TCAM_DETECT_BIST_DELAY        1
#define CTC_DKITS_TCAM_QUE_TCAM_DETECT_CAPTURE_DELAY     2

#define CTC_DKITS_TCAM_FLOW_KEY_UNIT             10      /* word */
#define CTC_DKITS_TCAM_UINT32_BITS               32

#define CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_L2KEY     0x0
#define CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_L3KEY     0x1
#define CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_L2L3KEY   0x2
#define CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_USERID    0x3

#define CTC_DKITS_TCAM_SCL_TCAM_BLOCK(block)         ((DKITS_TCAM_BLOCK_TYPE_IGS_SCL0 == block)    \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_SCL1 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_SCL2 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_SCL3 == block))

#define CTC_DKITS_TCAM_IGS_ACL_TCAM_BLOCK(block)     ((DKITS_TCAM_BLOCK_TYPE_IGS_ACL0 == block)    \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL1 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL2 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL3 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL3 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL4 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL5 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL6 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_IGS_ACL7 == block))

#define CTC_DKITS_TCAM_EGS_ACL_TCAM_BLOCK(block)     ((DKITS_TCAM_BLOCK_TYPE_EGS_ACL0 == block)    \
                                                     || (DKITS_TCAM_BLOCK_TYPE_EGS_ACL1 == block)  \
                                                     || (DKITS_TCAM_BLOCK_TYPE_EGS_ACL2 == block))

#define CTC_DKITS_TCAM_FLOW_TCAM_BLOCK(block)        (CTC_DKITS_TCAM_SCL_TCAM_BLOCK(block)         \
                                                     || CTC_DKITS_TCAM_IGS_ACL_TCAM_BLOCK(block)   \
                                                     || CTC_DKITS_TCAM_EGS_ACL_TCAM_BLOCK(block))

#define CTC_DKITS_TCAM_IP_TCAM_BLOCK(block)          ((DKITS_TCAM_BLOCK_TYPE_LPM_LKP0 == block)      \
                                                     || (DKITS_TCAM_BLOCK_TYPE_LPM_LKP1 == block))

#define CTC_DKITS_TCAM_IS_LPM_TCAM0(tcam_blk)          ((tcam_blk >= 0) && (tcam_blk <=3))
#define CTC_DKITS_TCAM_IS_LPM_TCAM1(tcam_blk)          ((tcam_blk >= 4) && (tcam_blk <=7))
#define CTC_DKITS_TCAM_IS_LPM_TCAM2(tcam_blk)          ((tcam_blk >= 8) && (tcam_blk <=11))

#define CTC_DKITS_TCAM_NAT_TCAM_BLOCK(block)         (DKITS_TCAM_BLOCK_TYPE_NAT_PBR == block)

#define CTC_DKITS_TCAM_CID_TCAM_BLOCK(block)         (DKITS_TCAM_BLOCK_TYPE_CATEGORYID == block)

#define CTC_DKITS_TCAM_QUE_TCAM_BLOCK(block)         (DKITS_TCAM_BLOCK_TYPE_SERVICE_QUEUE == block)

#define DKITS_TCAM_FLOW_RLT_INDEX(tcamid, index)     ((tcamid << (16 - DKITS_TCAM_FLOW_TCAM_BLK_BITS)) | index)
#define DKITS_TCAM_FLOW_RLT_TCAMID(index)            ((index >> (16 - DKITS_TCAM_FLOW_TCAM_BLK_BITS)) & ((1U << DKITS_TCAM_FLOW_TCAM_BLK_BITS) - 1))
#define DKITS_TCAM_FLOW_RLT_TCAMIDX(index)           (index & ((1U << (16 - DKITS_TCAM_FLOW_TCAM_BLK_BITS)) - 1))

#define DKITS_TCAM_IP_RLT_INDEX(tcamid, index)       ((tcamid << (15 - DKITS_TCAM_IP_TCAM_BLK_BITS)) | index)
#define DKITS_TCAM_IP_RLT_TCAMID(index)              ((index >> (15 - DKITS_TCAM_IP_TCAM_BLK_BITS)) & ((1U << DKITS_TCAM_IP_TCAM_BLK_BITS) - 1))
#define DKITS_TCAM_IP_RLT_TCAMIDX(index)             (index & ((1U << (15 - DKITS_TCAM_IP_TCAM_BLK_BITS)) - 1))

#define DKITS_TCAM_NAT_RLT_INDEX(tcamid, index)      ((tcamid << (14 - DKITS_TCAM_NAT_TCAM_BLK_BITS)) | index)
#define DKITS_TCAM_NAT_RLT_TCAMID(index)             ((index >> (14 - DKITS_TCAM_NAT_TCAM_BLK_BITS)) & ((1U << DKITS_TCAM_NAT_TCAM_BLK_BITS) - 1))
#define DKITS_TCAM_NAT_RLT_TCAMIDX(index)            (index & ((1U << (14 - DKITS_TCAM_NAT_TCAM_BLK_BITS)) - 1))

#define DKITS_TCAM_IP_NAT_TCAM(tblid)                ((EXT_INFO_TYPE_LPM_TCAM_IP == TABLE_EXT_INFO_TYPE(lchip, tblid))     \
                                                     || (EXT_INFO_TYPE_LPM_TCAM_NAT == TABLE_EXT_INFO_TYPE(lchip, tblid))  \
                                                     || (EXT_INFO_TYPE_TCAM_LPM_AD == TABLE_EXT_INFO_TYPE(lchip, tblid))   \
                                                     || (EXT_INFO_TYPE_TCAM_NAT_AD == TABLE_EXT_INFO_TYPE(lchip, tblid)))

#define CTC_DKITS_TCAM_ERROR_RETURN(op) \
    { \
        int32 rv = (op); \
        if ((rv < 0) || (1 == rv)) \
        { \
            CTC_DKIT_PRINT(" Dkits Error!! Fun:%s()  Line:%d ret:%d\n",__FUNCTION__,__LINE__, rv); \
            return (CLI_ERROR); \
        } \
    }
int32
sys_usw_dma_get_userid_type(uint8 lchip, uint8 value)
{
    uint32 type = 0;

    for (type = DRV_USERIDHASHTYPE_DOUBLEVLANPORT; type < DRV_USERIDPORTHASHTYPE_TRILL; type++)
    {
        if (value == DRV_ENUM(type))
        {
            return type;
        }
    }

    return DRV_DMA_MAX_CHAN_ID;
}

#define GET_USERID_TYPE(value) sys_usw_dma_get_userid_type(lchip, value)
struct dkits_tcam_tbl_info_s
{
    uint32  id           :16;
    uint32  idx          :14;
    uint32  result_valid :1;
    uint32  lookup_valid :1;
};
typedef struct dkits_tcam_tbl_info_s dkits_tcam_tbl_info_t;

struct dkits_tcam_capture_info_s
{
    dkits_tcam_tbl_info_t tbl[CTC_DKITS_TCAM_DETECT_MAX_REQ];
};
typedef struct dkits_tcam_capture_info_s dkits_tcam_capture_info_t;

struct ds_12word_key_s
{
    uint32 field[DRV_WORDS_PER_ENTRY * 20];
};
typedef struct ds_12word_key_s ds_12word_key_t;

char* tcam_block_desc[] = {"Ingress SCL0",           "Ingress SCL1",
                           "Ingress SCL2",           "Ingress SCL3",
                           "Ingress ACL0",           "Ingress ACL1",
                           "Ingress ACL2",           "Ingress ACL3",
                           "Ingress ACL4",           "Ingress ACL5",
                           "Ingress ACL6",           "Ingress ACL7",
                           "Egress ACL0",            "Egress ACL1",
                           "Egress ACL2",            "IP LPM First Lookup",
                           "IP LPM Second Lookup",   "IP PBR/NAT",
                           "CategoryID Lookup",      "Service QueueMap"};

ctc_dkits_tcam_tbl_t ctc_dkits_tcam_tbl[DKITS_TCAM_BLOCK_TYPE_NUM][DKITS_TCAM_PER_BLOCK_MAX_KEY_TYPE] =
{
    {{DsUserId0TcamKey80_t,                  DKITS_TCAM_SCL_KEY_USERID_3W,    0},
     {DsUserId0TcamKey160_t,                 DKITS_TCAM_SCL_KEY_USERID_6W,    0},
     {DsUserId0TcamKey320_t,                 DKITS_TCAM_SCL_KEY_USERID_12W,   0},
     {DsScl0MacKey160_t,                     DKITS_TCAM_SCL_KEY_L2,           0},
     {DsScl0L3Key160_t,                      DKITS_TCAM_SCL_KEY_L3_IPV4,      0},
     {DsScl0Ipv6Key320_t,                    DKITS_TCAM_SCL_KEY_L3_IPV6,      0},
     {DsScl0MacL3Key320_t,                   DKITS_TCAM_SCL_KEY_L2L3_IPV4,    0},
     {DsScl0MacIpv6Key640_t,                 DKITS_TCAM_SCL_KEY_L2L3_IPV6,    0},
     {MaxTblId_t,                            DKITS_TCAM_SCL_KEY_NUM,          0}},

    {{DsUserId1TcamKey80_t,                  DKITS_TCAM_SCL_KEY_USERID_3W,    0},
     {DsUserId1TcamKey160_t,                 DKITS_TCAM_SCL_KEY_USERID_6W,    0},
     {DsUserId1TcamKey320_t,                 DKITS_TCAM_SCL_KEY_USERID_12W,   0},
     {DsScl1MacKey160_t,                     DKITS_TCAM_SCL_KEY_L2,           0},
     {DsScl1L3Key160_t,                      DKITS_TCAM_SCL_KEY_L3_IPV4,      0},
     {DsScl1Ipv6Key320_t,                    DKITS_TCAM_SCL_KEY_L3_IPV6,      0},
     {DsScl1MacL3Key320_t,                   DKITS_TCAM_SCL_KEY_L2L3_IPV4,    0},
     {DsScl1MacIpv6Key640_t,                 DKITS_TCAM_SCL_KEY_L2L3_IPV6,    0},
     {MaxTblId_t,                            DKITS_TCAM_SCL_KEY_NUM,          0}},

    {{DsScl2MacKey160_t,                     DKITS_TCAM_SCL_KEY_L2,           0},
     {DsScl2L3Key160_t,                      DKITS_TCAM_SCL_KEY_L3_IPV4,      0},
     {DsScl2Ipv6Key320_t,                    DKITS_TCAM_SCL_KEY_L3_IPV6,      0},
     {DsScl2MacL3Key320_t,                   DKITS_TCAM_SCL_KEY_L2L3_IPV4,    0},
     {DsScl2MacIpv6Key640_t,                 DKITS_TCAM_SCL_KEY_L2L3_IPV6,    0},
     {MaxTblId_t,                            DKITS_TCAM_SCL_KEY_NUM,          0}},

    {{DsScl3L3Key160_t,                      DKITS_TCAM_SCL_KEY_L3_IPV4,      0},
     {DsScl3Ipv6Key320_t,                    DKITS_TCAM_SCL_KEY_L3_IPV6,      0},
     {DsScl3MacL3Key320_t,                   DKITS_TCAM_SCL_KEY_L2L3_IPV4,    0},
     {DsScl3MacIpv6Key640_t,                 DKITS_TCAM_SCL_KEY_L2L3_IPV6,    0},
     {MaxTblId_t,                            DKITS_TCAM_SCL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing0_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing0_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing0_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing0_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing0_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing0_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing0_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing0_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing0_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing0_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing0_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing0_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing0_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing0_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing1_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing1_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing1_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing1_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing1_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing1_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing1_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing1_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing1_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing1_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing1_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing1_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing1_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing1_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing2_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing2_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing2_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing2_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing2_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing2_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing2_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing2_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing2_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing2_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing2_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing2_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing2_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing2_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing3_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing3_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing3_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing3_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing3_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing3_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing3_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing3_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing3_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing3_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing3_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing3_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing3_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing3_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing4_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing4_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing4_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing4_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing4_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing4_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing4_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing4_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing4_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing4_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing4_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing4_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing4_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing4_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing5_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing5_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing5_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing5_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing5_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing5_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing5_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing5_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing5_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing5_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing5_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing5_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing5_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing5_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing6_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing6_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing6_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing6_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing6_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing6_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing6_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing6_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing6_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing6_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing6_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing6_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing6_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing6_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Ing7_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Ing7_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Ing7_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Ing7_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Ing7_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Ing7_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Ing7_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Ing7_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosCidKey160Ing7_t,               DKITS_TCAM_ACL_KEY_CID160,       0},
     {DsAclQosKey80Ing7_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {DsAclQosForwardKey320Ing7_t,           DKITS_TCAM_ACL_KEY_FORWARD320,   0},
     {DsAclQosForwardKey640Ing7_t,           DKITS_TCAM_ACL_KEY_FORWARD640,   0},
     {DsAclQosCoppKey320Ing7_t,              DKITS_TCAM_ACL_KEY_COPP320,      0},
     {DsAclQosCoppKey640Ing7_t,              DKITS_TCAM_ACL_KEY_COPP640,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Egr0_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Egr0_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Egr0_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Egr0_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Egr0_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Egr0_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Egr0_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Egr0_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosKey80Egr0_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Egr1_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Egr1_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Egr1_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Egr1_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Egr1_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Egr1_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Egr1_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Egr1_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosKey80Egr1_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsAclQosMacKey160Egr2_t,               DKITS_TCAM_ACL_KEY_MAC160,       0},
     {DsAclQosL3Key160Egr2_t,                DKITS_TCAM_ACL_KEY_L3160,        0},
     {DsAclQosL3Key320Egr2_t,                DKITS_TCAM_ACL_KEY_L3320,        0},
     {DsAclQosIpv6Key320Egr2_t,              DKITS_TCAM_ACL_KEY_IPV6320,      0},
     {DsAclQosIpv6Key640Egr2_t,              DKITS_TCAM_ACL_KEY_IPV6640,      0},
     {DsAclQosMacL3Key320Egr2_t,             DKITS_TCAM_ACL_KEY_MACL3320,     0},
     {DsAclQosMacL3Key640Egr2_t,             DKITS_TCAM_ACL_KEY_MACL3640,     0},
     {DsAclQosMacIpv6Key640Egr2_t,           DKITS_TCAM_ACL_KEY_MACIPV6640,   0},
     {DsAclQosKey80Egr2_t,                   DKITS_TCAM_ACL_KEY_SHORT80,      0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsLpmTcamIpv4DaPubHalfKey_t,           DKITS_TCAM_IP_KEY_IPV4UC,        0},
     {DsLpmTcamIpv6DaPubDoubleKey0_t,        DKITS_TCAM_IP_KEY_IPV6UC,        0},
     {DsLpmTcamIpv6DaPubSingleKey_t,         DKITS_TCAM_IP_KEY_IPV6UC,        0},
     {DsLpmTcamIpv6SaPubSingleKey_t,         DKITS_TCAM_IP_KEY_IPV6UC,        0},
     {MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{MaxTblId_t,                            DKITS_TCAM_ACL_KEY_NUM,          0}},

    {{DsLpmTcamIpv4NatDoubleKey_t,           DKITS_TCAM_NATPBR_KEY_IPV4NAT,   0},
     {MaxTblId_t,                            DKITS_TCAM_NATPBR_KEY_NUM,       0}},

    {{DsCategoryIdPairTcamKey_t,             0,                               0},
     {MaxTblId_t,                            0,                               0}},

    {{DsQueueMapTcamKey_t,                   0,                               0},
     {MaxTblId_t,                            0,                               0}}
};


#define ________DKITS_TCAM_INNER_FUNCTION__________

#define __0_CHIP_TCAM__

STATIC int32
_ctc_usw_dkits_tcam_get_lpm_tcam_blknum_index(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32 *blknum, uint32 *local_idx)
{
    uint16 addr_offset = 0;
    uint32 blk_id = 0;
    uint32 map_index = 0;

    if ((drv_usw_get_table_type(lchip, tbl_id) == DRV_TABLE_TYPE_LPM_TCAM_IP) || (drv_usw_get_table_type(lchip, tbl_id) == DRV_TABLE_TYPE_LPM_TCAM_NAT))
    {
        for (blk_id = 0; blk_id < DRV_CONST(DRV_MAX_LPM_TCAM_NUM); blk_id++)
        {
            CTC_DKITS_TCAM_ERROR_RETURN(drv_usw_get_tbl_index_base(lchip, tbl_id, index, &addr_offset));

            if (!DKITS_BMP_ISSET(TCAM_BITMAP(lchip, tbl_id), blk_id))
            {
                continue;
            }

            if ((index >= DRV_TCAM_START_INDEX(lchip, tbl_id, blk_id)) && (index <= TCAM_END_INDEX(lchip, tbl_id, blk_id)))
            {
                map_index = index - DRV_TCAM_START_INDEX(lchip, tbl_id, blk_id);

                *blknum = blk_id;
                *local_idx = map_index;

                break;
            }
        }
    }
    else if((drv_usw_get_table_type(lchip, tbl_id) == DRV_TABLE_TYPE_TCAM_LPM_AD) || (drv_usw_get_table_type(lchip, tbl_id) == DRV_TABLE_TYPE_TCAM_NAT_AD))
    {
        for (blk_id = 0; blk_id < DRV_CONST(DRV_MAX_LPM_TCAM_NUM); blk_id++)
        {
            CTC_DKITS_TCAM_ERROR_RETURN(drv_usw_get_tbl_index_base(lchip, tbl_id, index, &addr_offset));

            if (!DKITS_BMP_ISSET(TCAM_BITMAP(lchip, tbl_id), blk_id))
            {
                continue;
            }

            if ((index >= DRV_TCAM_START_INDEX(lchip, tbl_id, blk_id)) && (index <= TCAM_END_INDEX(lchip, tbl_id, blk_id)))
            {
                map_index = index - DRV_TCAM_START_INDEX(lchip, tbl_id, blk_id);

                *blknum = blk_id;
                *local_idx = map_index;

                break;
            }
        }
    }
    else
    {
        DRV_DBG_INFO("\nInvalid table id %d when get flow tcam block number and index!\n", tbl_id);
        return DRV_E_INVALID_TBL;
    }

    return DRV_E_NONE;
}

/**
 @brief Real embeded tcam read operation I/O
*/
STATIC int32
_ctc_usw_dkits_tcam_read_enque_tcam_entry(uint8 lchip, uint32 index, uint32* data, uint32* mask)
{
    uint32 qmgr_enq_tcam_mem[Q_MGR_ENQ_TCAM_MEM_BYTES/4] = {0};
    uint32 cmd = 0;
    int32  ret = DRV_E_NONE;
    uint8  chip_base = 0;
    uint32 lchip_offset = lchip + chip_base;
    uint32 idx = 0;
    uint32 entry_valid = 0;

    DRV_PTR_VALID_CHECK(data);

    /* drv_get_lchip_base(&chip_base); */

    idx = index;
    cmd = DRV_IOR(QMgrEnqTcamMem_t, DRV_ENTRY_FLAG);
    DRV_IF_ERROR_RETURN(DRV_IOCTL(lchip_offset, idx, cmd, qmgr_enq_tcam_mem));

    DRV_IOR_FIELD(lchip, QMgrEnqTcamMem_t, QMgrEnqTcamMem_tcamEntryValid_f, &entry_valid, qmgr_enq_tcam_mem);

    if(!entry_valid)
    {
        /* DRV_DBG_INFO("\nEnq Tcam Memory is invalid!\n"); */
        /* return DRV_E_INVALID_TCAM_TYPE; */
    }

    /* Read Tcam MASK field is X, DATA field is Y */
    sal_memcpy((uint8*)mask, (uint8*)qmgr_enq_tcam_mem,DS_QUEUE_MAP_TCAM_KEY_BYTES);
    sal_memcpy((uint8*)data,(uint8*)qmgr_enq_tcam_mem + DS_QUEUE_MAP_TCAM_KEY_BYTES, DS_QUEUE_MAP_TCAM_KEY_BYTES);

    return ret;
}

STATIC int32
_ctc_usw_dkits_tcam_read_cid_tcam_entry(uint8 lchip, uint32 index, uint32* data, uint32* mask)
{
    uint32 ipe_cid_tcam_mem[IPE_CID_TCAM_MEM_BYTES/4] = {0};
    uint32 cmd = 0;
    int32  ret = DRV_E_NONE;
    uint8  chip_base = 0;
    uint32 lchip_offset = lchip + chip_base;
    uint32 idx = 0;
    uint32 entry_valid = 0;

    DRV_PTR_VALID_CHECK(data);

    /* drv_get_lchip_base(&chip_base); */

    idx = index;
    cmd = DRV_IOR(IpeCidTcamMem_t, DRV_ENTRY_FLAG);
    DRV_IF_ERROR_RETURN(DRV_IOCTL(lchip_offset, idx, cmd, ipe_cid_tcam_mem));

    DRV_IOR_FIELD(lchip, IpeCidTcamMem_t, IpeCidTcamMem_tcamEntryValid_f, &entry_valid, ipe_cid_tcam_mem);

    if(!entry_valid)
    {
        /* DRV_DBG_INFO("\nCid Tcam Memory is invalid!\n"); */
        /* return DRV_E_INVALID_TCAM_TYPE; */
    }

     /* Read Tcam MASK field is X, DATA field is Y */
    sal_memcpy((uint8*)mask, (uint8*)ipe_cid_tcam_mem, DRV_CONST(DRV_DS_CATEGORY_ID_PAIR_TCAM_LOOKUP_KEY_BYTES));
    sal_memcpy((uint8*)data, (uint8*)ipe_cid_tcam_mem + DRV_CONST(DRV_DS_CATEGORY_ID_PAIR_TCAM_LOOKUP_KEY_BYTES),
              DRV_CONST(DRV_DS_CATEGORY_ID_PAIR_TCAM_LOOKUP_KEY_BYTES));

    return ret;
}

STATIC int32
_ctc_usw_dkits_tcam_read_flow_tcam_entry(uint8 lchip, uint32 blknum, uint32 index, uint32* data, uint32* mask)
{
    uint32 flow_tcam_tcam_mem[FLOW_TCAM_TCAM_MEM_BYTES/4] = {0};
    uint32 cmd = 0;
    int32  ret = DRV_E_NONE;
    uint8  chip_base = 0;
    uint32 lchip_offset = lchip + chip_base;
    uint32 idx = 0;
    uint32 entry_valid = 0;

    DRV_PTR_VALID_CHECK(data);

    /* drv_get_lchip_base(&chip_base); */
    idx = (blknum << 11) | index;
    cmd = DRV_IOR(FlowTcamTcamMem_t, DRV_ENTRY_FLAG);
    DRV_IF_ERROR_RETURN(DRV_IOCTL(lchip_offset, idx, cmd, flow_tcam_tcam_mem));

    DRV_IOR_FIELD(lchip, FlowTcamTcamMem_t, FlowTcamTcamMem_tcamEntryValid_f, &entry_valid, flow_tcam_tcam_mem);

    if(!entry_valid)
    {
        /* -DRV_DBG_INFO("\nFlow Tcam Memory is invalid!, idx:%d\n", idx); */
        /* -return DRV_E_INVALID_TCAM_TYPE; */
    }

    /*
    Read Tcam MASK field is X, DATA field is Y
    */
    sal_memcpy((uint8*)mask, (uint8*)flow_tcam_tcam_mem, DRV_BYTES_PER_ENTRY);
    sal_memcpy((uint8*)data, (uint8*)flow_tcam_tcam_mem + DRV_BYTES_PER_ENTRY, DRV_BYTES_PER_ENTRY);

    return ret;
}

STATIC int32
_ctc_usw_dkits_tcam_read_lpm_tcam_ip_entry(uint8 lchip, uint32 blknum, uint32 index, uint32* data, uint32* mask)
{
    uint32 lpm_tcam_tcam_mem[LPM_TCAM_TCAM_MEM_BYTES/4] = {0};
    uint32 cmd = 0;
    int32  ret = DRV_E_NONE;
    uint8  chip_base = 0;
    uint32 lchip_offset = lchip + chip_base;
    uint32 idx = 0;
    uint32 entry_valid = 0;

    DRV_PTR_VALID_CHECK(data);

    /* drv_get_lchip_base(&chip_base); */
    if (DRV_IS_DUET2(lchip))
    {
        idx = (blknum << (12)) | index;
    }
    else
    {
        idx = (blknum << (13)) | index;
    }

    cmd = DRV_IOR(LpmTcamTcamMem_t, DRV_ENTRY_FLAG);
    DRV_IF_ERROR_RETURN(DRV_IOCTL(lchip_offset, idx, cmd, lpm_tcam_tcam_mem));

    DRV_IOR_FIELD(lchip, LpmTcamTcamMem_t, LpmTcamTcamMem_tcamEntryValid_f, &entry_valid, lpm_tcam_tcam_mem);

    if(!entry_valid)
    {
        /* DRV_DBG_INFO("\nTcam Memory is invalid!\n"); */
        /* return DRV_E_INVALID_TCAM_TYPE; */
    }

     /* Read Tcam MASK field is X, DATA field is Y */
    sal_memcpy((uint8*)mask, (uint8*)lpm_tcam_tcam_mem, DRV_LPM_KEY_BYTES_PER_ENTRY);
    sal_memcpy((uint8*)data, (uint8*)lpm_tcam_tcam_mem + DRV_LPM_KEY_BYTES_PER_ENTRY, DRV_LPM_KEY_BYTES_PER_ENTRY);

    return ret;
}

/**
 @brief convert embeded tcam content from X/Y format to data/mask format
*/
STATIC int32
_ctc_usw_dkits_tcam_resolve_empty(uint8 lchip, uint32 tcam_entry_width, uint32 *data, uint32 *mask, uint32* p_is_empty)
{
    uint32 bit_pos = 0;
    uint32 index = 0, bit_offset = 0;

    /* data[1] -- [64,80]; data[2] -- [32,63]; data[3] -- [0,31] */
    for (bit_pos = 0; bit_pos < tcam_entry_width; bit_pos++)
    {
        index = bit_pos / 32;
        bit_offset = bit_pos % 32;

        if ((DKITS_IS_BIT_SET(data[index], bit_offset))
            && DKITS_IS_BIT_SET(mask[index], bit_offset))    /* X=1, Y=1: No Write but read. */
        {
            *p_is_empty |= 1;
            break;
        }
    }

    return CLI_SUCCESS;
}

int32
_ctc_usw_dkits_tcam_tbl_empty(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* p_empty)
{
    ds_t    data;
    ds_t    mask;
    uint32* p_mask = NULL;
    uint32* p_data = NULL;
    uint32  key_size = TABLE_EXT_INFO_PTR(lchip, tbl_id) ? DRV_TCAM_KEY_SIZE(lchip, tbl_id) : 0;
    uint32  entry_num_each_idx = 0, entry_idx = 0;
    bool    is_lpm_tcam = FALSE;
    /* uint8   lchip = lchip_offset + drv_init_chip_info.drv_init_lchip_base; */
    uint32  blknum = 0, local_idx = 0;
    tbl_entry_t entry;

    sal_memset(&data, 0, sizeof(data));
    sal_memset(&mask, 0, sizeof(mask));
    sal_memset(&entry, 0, sizeof(tbl_entry_t));

    entry.data_entry = (uint32 *)&data;
    entry.mask_entry = (uint32 *)&mask;

    DRV_INIT_CHECK(lchip);
    DRV_TBL_ID_VALID_CHECK(lchip, tbl_id);

    *p_empty = 0;

    if ((DRV_TABLE_TYPE_TCAM != drv_usw_get_table_type(lchip, tbl_id))
        && (DRV_TABLE_TYPE_LPM_TCAM_IP != drv_usw_get_table_type(lchip, tbl_id))
        && (DRV_TABLE_TYPE_LPM_TCAM_NAT != drv_usw_get_table_type(lchip, tbl_id))
        && (DRV_TABLE_TYPE_STATIC_TCAM_KEY != drv_usw_get_table_type(lchip, tbl_id)))
    {
        CTC_DKIT_PRINT("@@ DKIT ERROR! INVALID Tcam key TblID! %s %d %s, TblID: %u, \n",
                       __FILE__, __LINE__, __FUNCTION__, tbl_id);
        return CLI_ERROR;
    }

    if (DRV_TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        CTC_DKIT_PRINT("@@ DKIT ERROR! %s %d %s chip-0x%x, tbl-%d, index-0x%x exceeds the max_index-0x%x.\n",
                        __FILE__, __LINE__, __FUNCTION__, lchip, tbl_id, index, (uint32)DRV_TABLE_MAX_INDEX(lchip, tbl_id));
        return DRV_E_INVALID_TBL;
    }

    if (DRV_TABLE_TYPE_TCAM == drv_usw_get_table_type(lchip, tbl_id))
    {
        /* flow tcam w/r per 80bit */
        entry_num_each_idx = key_size / DRV_BYTES_PER_ENTRY;
        local_idx = local_idx * (key_size/DRV_BYTES_PER_ENTRY);
    }
    else if ((DRV_TABLE_TYPE_LPM_TCAM_IP == drv_usw_get_table_type(lchip, tbl_id))
            || (DRV_TABLE_TYPE_LPM_TCAM_NAT == drv_usw_get_table_type(lchip, tbl_id)))
    {
        is_lpm_tcam = TRUE;
        entry_num_each_idx = key_size / DRV_LPM_KEY_BYTES_PER_ENTRY;
    }
    else if (DRV_TABLE_TYPE_STATIC_TCAM_KEY == drv_usw_get_table_type(lchip, tbl_id))
    {
        entry_num_each_idx = 1;
        local_idx = index;
    }

    p_data = entry.data_entry;
    p_mask = entry.mask_entry;

    for (entry_idx = 0; entry_idx < entry_num_each_idx; entry_idx++)
    {
        /* read real tcam address */
        if (DsQueueMapTcamKey_t == tbl_id)
        {
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_read_enque_tcam_entry(lchip, local_idx, data, mask));
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_resolve_empty(lchip,
                                                                         DRV_TABLE_ENTRY_SIZE(lchip, tbl_id)*sizeof(uint32)*8,
                                                                         p_data, p_mask, p_empty));
        }
        else if (DsCategoryIdPairTcamKey_t == tbl_id)
        {
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_read_cid_tcam_entry(lchip, local_idx, data, mask));
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_resolve_empty(lchip,
                                                                         DRV_TABLE_ENTRY_SIZE(lchip, tbl_id)*sizeof(uint32)*8,
                                                                         p_data, p_mask, p_empty));
        }
        else if (!is_lpm_tcam)
        {
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_read_flow_tcam_entry(lchip, blknum, local_idx,
                                                                               data + entry_idx*DRV_WORDS_PER_ENTRY,
                                                                               mask + entry_idx*DRV_WORDS_PER_ENTRY));
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_resolve_empty(lchip,
                                                                         DRV_BYTES_PER_ENTRY*8,
                                                                         p_data + entry_idx*DRV_WORDS_PER_ENTRY,
                                                                         p_mask + entry_idx*DRV_WORDS_PER_ENTRY,
                                                                         p_empty));
        }
        else
        {
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_read_lpm_tcam_ip_entry(lchip, blknum, local_idx,
                                                                             data + entry_idx*DRV_LPM_WORDS_PER_ENTRY,
                                                                             mask + entry_idx*DRV_LPM_WORDS_PER_ENTRY));
            CTC_DKITS_TCAM_ERROR_RETURN(_ctc_usw_dkits_tcam_resolve_empty(lchip,
                                                                         DRV_LPM_KEY_BYTES_PER_ENTRY*8,
                                                                         p_data + entry_idx*DRV_LPM_WORDS_PER_ENTRY,
                                                                         p_mask + entry_idx*DRV_LPM_WORDS_PER_ENTRY,
                                                                         p_empty));
        }
        local_idx++;
    }

    return CLI_SUCCESS;
}

#define __1_COMMON__

STATIC int32
_ctc_usw_dkits_tcam_tbl2block(tbls_id_t tblid, dkits_tcam_block_type_t* p_block)
{
    if (DKITS_TCAM_IGS_SCL0_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_SCL0;
    }
    else if (DKITS_TCAM_IGS_SCL1_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_SCL1;
    }
    else if (DKITS_TCAM_IGS_SCL2_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_SCL2;
    }
    else if (DKITS_TCAM_IGS_SCL3_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_SCL3;
    }
    else if (DKITS_TCAM_IGS_ACL0_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL0;
    }
    else if (DKITS_TCAM_IGS_ACL1_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL1;
    }
    else if (DKITS_TCAM_IGS_ACL2_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL2;
    }
    else if (DKITS_TCAM_IGS_ACL3_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL3;
    }
    else if (DKITS_TCAM_IGS_ACL4_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL4;
    }
    else if (DKITS_TCAM_IGS_ACL5_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL5;
    }
    else if (DKITS_TCAM_IGS_ACL6_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL6;
    }
    else if (DKITS_TCAM_IGS_ACL7_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_IGS_ACL7;
    }
    else if (DKITS_TCAM_EGS_ACL0_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_EGS_ACL0;
    }
    else if (DKITS_TCAM_EGS_ACL1_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_EGS_ACL1;
    }
    else if (DKITS_TCAM_EGS_ACL2_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_EGS_ACL2;
    }
    else if (DKITS_TCAM_IPLKP0_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_LPM_LKP0;
    }
    else if (DKITS_TCAM_IPLKP1_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_LPM_LKP1;
    }
    else if (DKITS_TCAM_NATPBR_KEY(tblid))
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_NAT_PBR;
    }
    else if (DsCategoryIdPairTcamKey_t == tblid)
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_CATEGORYID;
    }
    else if (DsQueueMapTcamKey_t == tblid)
    {
        *p_block = DKITS_TCAM_BLOCK_TYPE_SERVICE_QUEUE;
    }
    else
    {
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

/* offset input unit is DKITS_LPM_TCAM_MODULE_XXX, output unit is 12 lpm tcam block */
STATIC int32
_ctc_usw_dkits_tcam_lpm_block2offset(uint32 blknum, uint32* p_offset)
{
    switch (blknum)
    {
    case 0:
    case 4:
    case 8:
        ;
        break;
    case 1:
        *p_offset = DRV_LPM_TCAM_KEY0_MAX_ENTRY_NUM;
        break;
    case 2:
        *p_offset = DRV_LPM_TCAM_KEY0_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY1_MAX_ENTRY_NUM;
        break;
    case 3:
        *p_offset = DRV_LPM_TCAM_KEY0_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY1_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY2_MAX_ENTRY_NUM;
        break;
    case 5:
        *p_offset = DRV_LPM_TCAM_KEY4_MAX_ENTRY_NUM;
        break;
    case 6:
        *p_offset = DRV_LPM_TCAM_KEY4_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY5_MAX_ENTRY_NUM;
        break;
    case 7:
        *p_offset = DRV_LPM_TCAM_KEY4_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY5_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY6_MAX_ENTRY_NUM;
        break;
    case 9:
        *p_offset = DRV_LPM_TCAM_KEY8_MAX_ENTRY_NUM;
        break;
    case 10:
        *p_offset = DRV_LPM_TCAM_KEY8_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY9_MAX_ENTRY_NUM;
        break;
    case 11:
        *p_offset = DRV_LPM_TCAM_KEY8_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY9_MAX_ENTRY_NUM + DRV_LPM_TCAM_KEY10_MAX_ENTRY_NUM;
        break;
    default:
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

int32
ctc_usw_dkits_tcam_entry_offset(uint8 lchip, tbls_id_t tblid, uint32 tbl_idx, uint32* p_offset, uint32* p_tcam_blk)
{
    uint32 idx = 0;
    uint32 block = 0;
    uint32 entry_offset = 0;

    CTC_DKITS_TCAM_ERROR_RETURN(drv_usw_ftm_get_entry_num(lchip, tblid, &idx));
    if (0 == idx)
    {
        CTC_DKIT_PRINT_DEBUG("%s %d, %s is not allocate.\n", __FUNCTION__, __LINE__, DRV_TABLE_NAME(lchip, tblid));
        return CLI_SUCCESS;
    }

    _ctc_usw_dkits_tcam_tbl2block(tblid, &block);

    if (CTC_DKITS_TCAM_FLOW_TCAM_BLOCK(block))
    {
        /* unit is 3w */
        *p_offset = idx * (DRV_TCAM_KEY_SIZE(lchip, tblid)/DRV_BYTES_PER_ENTRY);
    }
    else if (CTC_DKITS_TCAM_IP_TCAM_BLOCK(block) || CTC_DKITS_TCAM_NAT_TCAM_BLOCK(block))
    {
        _ctc_usw_dkits_tcam_get_lpm_tcam_blknum_index(lchip, tblid, tbl_idx, p_tcam_blk, &idx);
        _ctc_usw_dkits_tcam_lpm_block2offset(*p_tcam_blk, &entry_offset);
         /*drv_chip_lpm_tcam_get_blknum_index(lchip, tblid, tbl_idx, p_tcam_blk, &idx);*/

        /* unit is 2w */
        *p_offset = (idx * (DRV_TCAM_KEY_SIZE(lchip, tblid)/DRV_LPM_KEY_BYTES_PER_ENTRY)) + entry_offset;
    }
    else if ((DKITS_TCAM_BLOCK_TYPE_CATEGORYID == block) || (DKITS_TCAM_BLOCK_TYPE_SERVICE_QUEUE == block))
    {
        *p_offset = tbl_idx;
    }

    return CLI_SUCCESS;
}

int32
ctc_usw_dkits_tcam_parser_key_type(uint8 lchip, tbls_id_t tblid, tbl_entry_t* p_tcam_key, uint32* p_tcam_key_type, uint32* p_ad_type)
{
    uint32 hash_type = 0, is_ipv6 = 0;

    if (DKITS_TCAM_IGS_SCL0_KEY(tblid) || DKITS_TCAM_IGS_SCL1_KEY(tblid)
        || DKITS_TCAM_IGS_SCL2_KEY(tblid) || DKITS_TCAM_IGS_SCL3_KEY(tblid))
    {
        if (DKITS_TCAM_IGS_SCL0_CFL(tblid) || DKITS_TCAM_IGS_SCL1_CFL(tblid))
        {
            hash_type = GetDsUserId0TcamKey80(V, hashType_f, p_tcam_key->data_entry);
            hash_type &= GetDsUserId0TcamKey80(V, hashType_f, p_tcam_key->mask_entry);

            switch (GET_USERID_TYPE(hash_type))
            {
            case DRV_USERIDHASHTYPE_DOUBLEVLANPORT:
            case DRV_USERIDHASHTYPE_CVLANPORT:
            case DRV_USERIDHASHTYPE_SVLANPORT:
            case DRV_USERIDHASHTYPE_PORT:
            case DRV_USERIDHASHTYPE_CVLANCOSPORT:
            case DRV_USERIDHASHTYPE_SVLANCOSPORT:
            case DRV_USERIDHASHTYPE_MAC:
            case DRV_USERIDHASHTYPE_MACPORT:
            case DRV_USERIDHASHTYPE_IPV4SA:
            case DRV_USERIDHASHTYPE_IPV4PORT:
            case DRV_USERIDHASHTYPE_TUNNELIPV4DA:
            case DRV_USERIDHASHTYPE_TUNNELIPV4GREKEY:
            case DRV_USERIDHASHTYPE_TUNNELIPV4RPF:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4MCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4MCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4CAPWAP:
            case DRV_USERIDHASHTYPE_TUNNELCAPWAPRMAC:
            case DRV_USERIDHASHTYPE_TUNNELCAPWAPRMACRID:
            case DRV_USERIDHASHTYPE_CAPWAPSTASTATUS:
            case DRV_USERIDHASHTYPE_CAPWAPSTASTATUSMC:
            case DRV_USERIDHASHTYPE_CAPWAPVLANFORWARD:
            case DRV_USERIDHASHTYPE_CAPWAPMACDAFORWARD:
            case DRV_USERIDHASHTYPE_TUNNELMPLS:
                *p_tcam_key_type = DKITS_TCAM_SCL_KEY_USERID_3W;
                break;

            /*160*/
            case DRV_USERIDHASHTYPE_IPV6SA:
            case DRV_USERIDHASHTYPE_TUNNELIPV4:
            case DRV_USERIDHASHTYPE_TUNNELIPV4NVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4VXLANMODE1:
            case DRV_USERIDHASHTYPE_SCLFLOWL2:
                *p_tcam_key_type = DKITS_TCAM_SCL_KEY_USERID_6W;
                break;

            /*320*/
            case DRV_USERIDHASHTYPE_IPV6PORT:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6CAPWAP:
                *p_tcam_key_type = DKITS_TCAM_SCL_KEY_USERID_12W;
                break;

            default:
                if(hash_type == DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4DA))
                {
                    *p_tcam_key_type = DKITS_TCAM_SCL_KEY_USERID_3W;
                }
                else if(hash_type == DRV_ENUM(DRV_USERIDHASHTYPE_SCLFLOWL2))
                {
                    *p_tcam_key_type = DKITS_TCAM_SCL_KEY_USERID_6W;
                }
                else
                {
                    *p_tcam_key_type = DKITS_TCAM_SCL_KEY_NUM;
                }
                break;
            }

            switch (hash_type)
            {
            /* The key contains port info be decide ad type by DsPhyPortExt's tcam1IsSclFlow. */
            case DRV_USERIDHASHTYPE_DOUBLEVLANPORT:
            case DRV_USERIDHASHTYPE_SVLANPORT:
            case DRV_USERIDHASHTYPE_CVLANPORT:
            case DRV_USERIDHASHTYPE_SVLANCOSPORT:
            case DRV_USERIDHASHTYPE_CVLANCOSPORT:
            case DRV_USERIDHASHTYPE_MACPORT:
            case DRV_USERIDHASHTYPE_IPV4PORT:
            case DRV_USERIDHASHTYPE_PORT:
            case DRV_USERIDHASHTYPE_IPV6PORT:

            case DRV_USERIDHASHTYPE_MAC:
            case DRV_USERIDHASHTYPE_IPV4SA:
            case DRV_USERIDHASHTYPE_SVLANMACSA:
            case DRV_USERIDHASHTYPE_SVLAN:
            case DRV_USERIDHASHTYPE_ECIDNAMESPACE:
            case DRV_USERIDHASHTYPE_INGECIDNAMESPACE:
            case DRV_USERIDHASHTYPE_IPV6SA:
            case DRV_USERIDHASHTYPE_CAPWAPSTASTATUS:
            case DRV_USERIDHASHTYPE_CAPWAPSTASTATUSMC:
            case DRV_USERIDHASHTYPE_CAPWAPMACDAFORWARD:
            case DRV_USERIDHASHTYPE_CAPWAPVLANFORWARD:
                *p_ad_type = DKITS_TCAM_SCL_AD_USERID;
                break;

            case DRV_USERIDHASHTYPE_TUNNELIPV4:
            case DRV_USERIDHASHTYPE_TUNNELIPV4GREKEY:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UDP:
            case DRV_USERIDHASHTYPE_TUNNELPBB:
            case DRV_USERIDHASHTYPE_TUNNELTRILLUCRPF:
            case DRV_USERIDHASHTYPE_TUNNELTRILLUCDECAP:
            case DRV_USERIDHASHTYPE_TUNNELTRILLMCRPF:
            case DRV_USERIDHASHTYPE_TUNNELTRILLMCDECAP:
            case DRV_USERIDHASHTYPE_TUNNELTRILLMCADJ:
            case DRV_USERIDHASHTYPE_TUNNELIPV4RPF:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4MCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4VXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4MCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV4NVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE0:
            case DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE1:
            case DRV_USERIDHASHTYPE_TUNNELIPV4CAPWAP:
            case DRV_USERIDHASHTYPE_TUNNELIPV6CAPWAP:
            case DRV_USERIDHASHTYPE_TUNNELCAPWAPRMAC:
            case DRV_USERIDHASHTYPE_TUNNELCAPWAPRMACRID:
            case DRV_USERIDHASHTYPE_TUNNELIPV4DA:
            case DRV_USERIDHASHTYPE_TUNNELMPLS:
                *p_ad_type = DKITS_TCAM_SCL_AD_TUNNEL;
                break;
            case DRV_USERIDHASHTYPE_SCLFLOWL2:
                *p_ad_type = DKITS_TCAM_SCL_AD_FLOW;
                break;
            default:
                if(hash_type == DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4DA))
                {
                    *p_ad_type = DKITS_TCAM_SCL_AD_TUNNEL;
                }
                else if(hash_type == DRV_ENUM(DRV_USERIDHASHTYPE_SCLFLOWL2))
                {
                    *p_ad_type = DKITS_TCAM_SCL_AD_FLOW;
                }
                else
                {
                    *p_ad_type = DKITS_TCAM_SCL_AD_NUM;
                }
            }
        }
        else
        {
            *p_tcam_key_type = GetDsScl0MacKey160(V, sclKeyType0_f, p_tcam_key->data_entry);
            *p_tcam_key_type &= GetDsScl0MacKey160(V, sclKeyType0_f, p_tcam_key->mask_entry);

            if (CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_L3KEY == *p_tcam_key_type)
            {
                is_ipv6  = GetDsScl0L3Key160(V, isIpv6Key_f, p_tcam_key->data_entry);
                is_ipv6 &= GetDsScl0L3Key160(V, isIpv6Key_f, p_tcam_key->mask_entry);
                *p_tcam_key_type = (is_ipv6) ? DKITS_TCAM_SCL_KEY_L3_IPV6 : DKITS_TCAM_SCL_KEY_L3_IPV4;
            }
            else if (CTC_DKITS_TCAM_SCL_KEY_DRV_TYPE_L2L3KEY == *p_tcam_key_type)
            {
                is_ipv6  = GetDsScl1MacL3Key320(V, isIpv6Key_f, p_tcam_key->data_entry);
                is_ipv6 &= GetDsScl1MacL3Key320(V, isIpv6Key_f, p_tcam_key->mask_entry);
                *p_tcam_key_type = (is_ipv6) ? DKITS_TCAM_SCL_KEY_L2L3_IPV6 : DKITS_TCAM_SCL_KEY_L2L3_IPV4;
            }
            *p_ad_type = GetDsScl0MacKey160(V, _type_f, p_tcam_key->data_entry);
            *p_ad_type &= GetDsScl0MacKey160(V, _type_f, p_tcam_key->mask_entry);
        }
    }
    else if (DKITS_TCAM_IGS_ACL0_KEY(tblid) || DKITS_TCAM_IGS_ACL1_KEY(tblid)
            || DKITS_TCAM_IGS_ACL2_KEY(tblid) || DKITS_TCAM_IGS_ACL3_KEY(tblid)
            || DKITS_TCAM_IGS_ACL4_KEY(tblid) || DKITS_TCAM_IGS_ACL5_KEY(tblid)
            || DKITS_TCAM_IGS_ACL6_KEY(tblid) || DKITS_TCAM_IGS_ACL7_KEY(tblid)
            || DKITS_TCAM_EGS_ACL0_KEY(tblid) || DKITS_TCAM_EGS_ACL1_KEY(tblid)
            || DKITS_TCAM_EGS_ACL2_KEY(tblid))
    {
        if ((DsAclQosKey80Ing0_t == tblid) || (DsAclQosKey80Ing1_t == tblid)
           || (DsAclQosKey80Ing2_t == tblid) || (DsAclQosKey80Ing3_t == tblid)
           || (DsAclQosKey80Ing4_t == tblid) || (DsAclQosKey80Ing5_t == tblid)
           || (DsAclQosKey80Ing6_t == tblid) || (DsAclQosKey80Ing7_t == tblid)
           || (DsAclQosKey80Egr0_t == tblid) || (DsAclQosKey80Egr1_t == tblid)
           || (DsAclQosKey80Egr2_t == tblid) || (DsAclQosCoppKey640Ing0_t == tblid)
           || (DsAclQosCoppKey640Ing1_t == tblid) || (DsAclQosCoppKey640Ing2_t == tblid)
           || (DsAclQosCoppKey640Ing3_t == tblid) || (DsAclQosCoppKey640Ing4_t == tblid)
           || (DsAclQosCoppKey640Ing5_t == tblid) || (DsAclQosCoppKey640Ing6_t == tblid)
           || (DsAclQosCoppKey640Ing7_t == tblid))
        {
            /*cannot get correct 80bit key_type from key, not support 80bit key bist*/
            *p_tcam_key_type = DKITS_TCAM_ACL_KEY_NUM;
        }
        else
        {
            *p_tcam_key_type = GetDsAclQosMacKey160Ing0(V, aclQosKeyType_f, p_tcam_key->data_entry);
            *p_tcam_key_type &= GetDsAclQosMacKey160Ing0(V, aclQosKeyType_f, p_tcam_key->mask_entry);
        }
    }
    else if (DKITS_TCAM_IPLKP0_KEY(tblid) || DKITS_TCAM_IPLKP1_KEY(tblid))
    {
        *p_tcam_key_type = GetDsLpmTcamIpv4HalfKey(V, lpmTcamKeyType_f, p_tcam_key->data_entry);
        *p_tcam_key_type &= GetDsLpmTcamIpv4HalfKey(V, lpmTcamKeyType_f, p_tcam_key->mask_entry);
    }
    else if (DKITS_TCAM_NATPBR_KEY(tblid))
    {
        *p_tcam_key_type = GetDsLpmTcamIpv4PbrDoubleKey(V, lpmTcamKeyType_f, p_tcam_key->data_entry);
        *p_tcam_key_type &= GetDsLpmTcamIpv4PbrDoubleKey(V, lpmTcamKeyType_f, p_tcam_key->mask_entry);
    }
    else if (DsCategoryIdPairTcamKey_t == tblid)
    {
        *p_tcam_key_type = 0;
    }
    else if (DsQueueMapTcamKey_t == tblid)
    {
        *p_tcam_key_type = 0;
    }
    else
    {
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

int32
ctc_usw_dkits_tcam_read_tcam_key(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* p_empty, tbl_entry_t* p_tcam_key)
{
    int32  ret = 0;
    uint32 cmd = 0;
    ds_t mask_entry_tmp;
    sal_memset(p_tcam_key->mask_entry, 0, sizeof(ds_t));
    sal_memset(&mask_entry_tmp, 0, sizeof(ds_t));

    if (DRV_TABLE_MAX_INDEX(lchip, tbl_id) <= index)
    {
        CTC_DKIT_PRINT("@@ DKIT ERROR! %s %d %s chip-0x%x, tbl-%d, index-0x%x exceeds the max_index-0x%x.\n",
                        __FILE__, __LINE__, __FUNCTION__, lchip, tbl_id, index, (uint32)DRV_TABLE_MAX_INDEX(lchip, tbl_id));
        return CLI_ERROR;
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, index, cmd, p_tcam_key);
    if (ret < 0)
    {
        CTC_DKIT_PRINT("Read tcam key %s:%u error!\n", DRV_TABLE_NAME(lchip, tbl_id), index);
        return CLI_ERROR;
    }

    if (0 == SDK_WORK_PLATFORM)
    {
        _ctc_usw_dkits_tcam_tbl_empty(lchip, tbl_id, index, p_empty);
    }
    else /*uml*/
    {
        if (sal_memcmp((uint8*)p_tcam_key->mask_entry, (uint8*)&mask_entry_tmp, DRV_TCAM_KEY_SIZE(lchip, tbl_id)))
        {
            *p_empty = 0;
        }
        else
        {
            *p_empty = 1;
        }
    }

    return CLI_SUCCESS;
}

